//package com.hz.tgb.data.redis.example.config;
//
//import com.ctrip.framework.apollo.model.ConfigChangeEvent;
//import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
//import com.fasterxml.jackson.annotation.JsonAutoDetect;
//import com.fasterxml.jackson.annotation.PropertyAccessor;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.yl.redis.exception.RedisException;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cache.CacheManager;
//import org.springframework.cloud.context.scope.refresh.RefreshScope;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.data.redis.cache.RedisCacheConfiguration;
//import org.springframework.data.redis.cache.RedisCacheManager;
//import org.springframework.data.redis.cache.RedisCacheWriter;
//import org.springframework.data.redis.connection.*;
//import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
//import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
//import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
//import org.springframework.data.redis.serializer.RedisSerializationContext;
//import org.springframework.data.redis.serializer.RedisSerializer;
//import org.springframework.util.CollectionUtils;
//import org.springframework.util.StringUtils;
//
//import java.time.Duration;
//import java.util.Objects;
//
//@Configuration
//@Slf4j
//public class RedisConfiguration {
//
//    @Bean
//    public RedisConfigBean getRedisConfigBean() {
//        return new RedisConfigBean();
//    }
//
//    @Autowired
//    private RedisConfigBean redisConfigBean;
//    @Autowired
//    private RefreshScope refreshScope;
//
//    @Bean
//    public RedisConnectionFactory getConnectionFactory() {
//        log.info("redis config node: {}", redisConfigBean.getNodesInfoList());
//        if (CollectionUtils.isEmpty(redisConfigBean.getNodesInfoList())) {
//            throw new RedisException("nodesInfo is empty");
//        }
//
//        int nodeSize = redisConfigBean.getNodesInfoList().size();
//        String password = redisConfigBean.getPassword();
//        if (nodeSize == 1) {
//            // 单机模式
//            RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
//            RedisNode redisNode = redisConfigBean.getNodesInfoList().get(0);
//            configuration.setHostName(Objects.requireNonNull(redisNode.getHost()));
//            configuration.setPort(Objects.requireNonNull(redisNode.getPort()));
//            configuration.setDatabase(0);
//            if (!StringUtils.isEmpty(password)) {
//                configuration.setPassword(RedisPassword.of(password));
//            }
//            // factory.setShareNativeConnection(false);//是否允许多个线程操作共用同一个缓存连接，默认true，false时每个操作都将开辟新的连接
//            return new LettuceConnectionFactory(configuration);
//        } else {
//            // cluster模式
//            RedisClusterConfiguration configuration = new RedisClusterConfiguration();
//            configuration.setClusterNodes(redisConfigBean.getNodesInfoList());
//            configuration.setMaxRedirects(redisConfigBean.getNodesInfoList().size());
//            if (!StringUtils.isEmpty(password)) {
//                configuration.setPassword(RedisPassword.of(password));
//            }
//            // factory.setShareNativeConnection(false);//是否允许多个线程操作共用同一个缓存连接，默认true，false时每个操作都将开辟新的连接
//            return new LettuceConnectionFactory(configuration, getPoolConfig());
//        }
//
//    }
//
//    @Bean
//    public LettucePoolingClientConfiguration getPoolConfig() {
//        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
//        poolConfig.setMaxTotal(redisConfigBean.getMaxTotal() != null ? redisConfigBean.getMaxTotal() : GenericObjectPoolConfig.DEFAULT_MAX_TOTAL);
//        poolConfig.setMaxWaitMillis(1000);
//        log.info("redis maxTotal connection: {}", poolConfig.getMaxTotal());
//        return LettucePoolingClientConfiguration.builder()
//                .poolConfig(poolConfig)
//                //.commandTimeout(Duration.ofMillis(1000))
//                //.shutdownTimeout(Duration.ofMillis(5000))
//                .build();
//    }
//
//    @Bean(name = "redisTemplate")
//    public RedisTemplate<String, Object> getRedisTemplate() {
//        // 只能对字符串的键值操作
//        RedisTemplate<String, Object> template = new RedisTemplate<>();
//        template.setConnectionFactory(getConnectionFactory());
//
//        // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
//        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
//        ObjectMapper om = new ObjectMapper();
//        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        jackson2JsonRedisSerializer.setObjectMapper(om);
//
//        template.setKeySerializer(jackson2JsonRedisSerializer);
//        template.setValueSerializer(jackson2JsonRedisSerializer);
//        template.setHashKeySerializer(jackson2JsonRedisSerializer);
//        template.setHashValueSerializer(jackson2JsonRedisSerializer);
//        template.afterPropertiesSet();
//
//        return template;
//    }
//
//    @ApolloConfigChangeListener(value = {"redis.yml"})
//    public void onChange(ConfigChangeEvent changeEvent) {
//        boolean ischanged = false;
//        for (String changeKey : changeEvent.changedKeys()) {
//            if (changeKey.startsWith("redis")) {
//                ischanged = true;
//                break;
//            }
//        }
//        if (!ischanged) {
//            return;
//        }
//        refreshScope.refresh("redisConfigBean");
//    }
//
//    /**
//     * 缓存管理器
//     */
//    @Bean
//    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//        // 初始化一个RedisCacheWriter
//        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
//        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer);
//        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
//                // 设置CacheManager的值序列化方式为json序列化
//                .serializeValuesWith(pair)
//                // 设置缓存有效期
//                .entryTtl(Duration.ofSeconds(redisConfigBean.getCacheExpireTime() != null ? redisConfigBean.getCacheExpireTime() : 60));
//        return RedisCacheManager
//                .builder(redisCacheWriter)
//                .cacheDefaults(redisCacheConfiguration).build();
//    }
//
//}